const chalk = require("chalk");

const Koa = require("koa");
const Router = require("koa-router");
const Redis = require("ioredis");
const koaStatic = require("koa-static");
const compose = require("koa-compose");
const { koaBody } = require("koa-body");
const path = require("path");
const os = require("os");
const routes = require("./routes");
const cors = require("koa2-cors");

const app = new Koa();
const redis = new Redis();
const router = new Router();

app.use(
  cors({
    origin: "*", // 允许所有域名访问
    credentials: true, // 允许携带cookie
  })
);

/**
 * 获取当前机器的ip地址
 */
function getIpAddress() {
  var ifaces = os.networkInterfaces();

  for (var dev in ifaces) {
    let iface = ifaces[dev];

    for (let i = 0; i < iface.length; i++) {
      let { family, address, internal } = iface[i];

      if (family === "IPv4" && address !== "127.0.0.1" && !internal) {
        return address;
      }
    }
  }
}

const errorHandler = async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    ctx.response.status = err.statusCode || err.status || 500;
    ctx.response.type = "html";
    ctx.response.body = "<p>Something wrong, please contact administrator.</p>";
    ctx.app.emit("error", err, ctx);
  }
};

Object.entries(routes).forEach(([name, route]) => {
  // get 、 put 、 post 、 patch 、 delete 、 del
  router[route.method ?? "get"](
    `/${route.name ?? name}`,
    typeof route === "function" ? route : route.handler
  );
});

router.get("/", async (ctx) => {
  ctx.response.type = "html";
  const routesArray = Array.from(
    new Set(router.stack.map((layer) => layer.path))
  ).map((it) => {
    return `<li><a href='${it}'>${it}</a></li>`;
  });
  routesArray.push(`<li><a href='/html/word.html'>/My Vocabulary</a></li>`);
  ctx.response.body = routesArray.join("");
});

const middlewares = compose([
  errorHandler,
  koaStatic(path.join(__dirname, "static")),
  koaBody(),
]);
app.use(middlewares);
app.use(async (ctx, next) => {
  ctx.redis = redis;
  await next();
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
  console.log(
    chalk.green("http://127.0.0.1:3000/"),
    "or",
    chalk.green(`http://${getIpAddress()}:3000/`)
  );
});

app.on("error", (err, ctx) => console.error("server error ====> \r", err));
